module branch_unit(
  input [7:0] op,
  input [63:0] src1,
  input [63:0] src2,
  input [63:0] imm,
  input [63:0] pc_i,

  output [63:0] pc_o,
  output pc_valid_o,
  output [63:0] res,
  output valid_o
);
  /*verilator no_inline_module*/ 
  wire op_beq/*verilator public_flat*/ ,op_bge/*verilator public_flat*/ ,op_bgeu/*verilator public_flat*/ ,op_blt/*verilator public_flat*/ ,op_bltu/*verilator public_flat*/ ,op_bne/*verilator public_flat*/ ,op_jal/*verilator public_flat*/ ,op_jalr/*verilator public_flat*/ ;
  assign {op_beq,op_bge,op_bgeu,op_blt,op_bltu,op_bne,op_jal,op_jalr} = op;

  wire [63:0] pc_r /*verilator public_flat*/ = ({64{op_jal|op_beq|op_bne|op_bge|op_bgeu|op_blt|op_bltu}}&(pc_i+imm) | {64{op_jalr}}&(src1+imm));

  assign pc_o = {pc_r[63:1],1'b0};

  wire eq  /*verilator public_flat*/ = src1==src2;
  wire ne  /*verilator public_flat*/ = !eq;
  wire ge  /*verilator public_flat*/ = $signed(src1) >= $signed(src2);
  wire geu /*verilator public_flat*/ = src1 >= src2;
  wire lt  /*verilator public_flat*/ = !ge;
  wire ltu /*verilator public_flat*/ = !geu;

  assign res = {64{valid_o}}&(pc_i + 64'h4);
  assign pc_valid_o = op_jal | op_jalr | (op_beq&eq) | (op_bne&ne) | (op_bge&ge) | (op_bgeu&geu) | (op_blt&lt) | (op_bltu&ltu); 
  assign valid_o = op_jal | op_jalr;
endmodule
